package com.ksyun.client.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ksyun.client.domain.dto.HeartBeat;
import com.ksyun.client.domain.dto.ServiceInstance;
import com.ksyun.client.service.ClientService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@RequiredArgsConstructor
public class ClientServiceImpl implements ClientService {
    private ServiceInstance serviceInstance=null;
    private static final String serviceId = UUID.randomUUID().toString();
    @Override
    public String geturl() {
        //向注册中心发起询问
        String registerUrl="http://localhost:8880/api/discovery?name=time-service";
        //接收返回的ServiceInstance对象
        ObjectMapper objectMapper = new ObjectMapper();
        List<ServiceInstance> serviceInstances = null;

        // 创建 HTTP 客户端
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(registerUrl);

            // 执行 GET 请求
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                // 检查响应状态
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode == 200) {
                    // 读取响应体
                    String responseBody = EntityUtils.toString(response.getEntity());
                    // 解析响应体为 List<ServiceInstance> 对象
                    serviceInstances = objectMapper.readValue(responseBody, new TypeReference<List<ServiceInstance>>(){});
                } else {

                }
            }
        } catch (Exception e) {
        }
        if (serviceInstances==null||serviceInstances.isEmpty()){
            return null;
        }else {
            ServiceInstance serviceInstance = serviceInstances.get(0);
            String ipAddress = serviceInstance.getIpAddress();
            int port = serviceInstance.getPort();
            String res="http://"+ipAddress+":"+port+"/api/getDateTime?style=full";
            return res;
        }
    }
    private ScheduledExecutorService scheduledExecutorService;
    private Runnable registrationTask;
    @Override
    public void awake(ServiceInstance serviceInstance) {
        this.serviceInstance=serviceInstance;
        // 如果定时任务已经启动，则不再启动
        if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) {
            return;
        }
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

        // 定义定时任务
        registrationTask = () -> {
            try {
                // 这里将调用发送 POST 请求的逻辑，使用 sendPostRequest 方法
                sendPostRequest(serviceInstance);
            } catch (Exception e) {

            }
        };
        // 每隔一定时间（例如每 60 秒）执行一次注册
        scheduledExecutorService.scheduleAtFixedRate(registrationTask, 0, 50, TimeUnit.SECONDS);
    }

    @Override
    public void sleep(ServiceInstance serviceInstance) {
        this.serviceInstance=null;
        // 关闭定时任务
        if (scheduledExecutorService != null) {
            scheduledExecutorService.shutdownNow(); // 关闭定时任务
            scheduledExecutorService = null;
        }

    }
    private void sendPostRequest(ServiceInstance serviceInstance) throws Exception{
        // 实现向注册中心发送 POST 请求的逻辑
        HeartBeat heartBeat=new HeartBeat(serviceInstance.getServiceId(),serviceInstance.getIpAddress(),serviceInstance.getPort());
        //向客户端发送请求
        ObjectMapper objectMapper=new ObjectMapper();
        String json = objectMapper.writeValueAsString(heartBeat);
        String ipAddress = serviceInstance.getIpAddress();
        int port = serviceInstance.getPort();
        // 尝试调用远程的 heart
        String url = "http://localhost:81/api/heartbeat";

        HttpPost httpPost = new HttpPost(url);
        StringEntity entity = new StringEntity(json);
        // 设置 Content-Type
        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setEntity(entity);
        // 设置超时
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(200) // 连接超时设置为0.2秒
                .setSocketTimeout(200)  // 读取超时设置为0.2秒
                .build();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            // 处理响应,不需要处理
        } catch (Exception e) {
        } finally {
            httpClient.close(); // 确保客户端被关闭
        }
    }

    @Scheduled(fixedRate = 1000)
    public void writeLog(){
        if (serviceInstance!=null&&serviceInstance.getServiceId()!=null){
            String logMessage = createLogMessage("Client status is OK.");
            writeLogToFile(logMessage);
        }else {
            //该服务停止，写入的为服务停止
            String logMessage = createFaiedLogMessage("Client status is OffLine.");
            writeFaiedLogToFile(logMessage);
        }
    }
    private String createFaiedLogMessage(String message) {
        String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
        return String.format("[%s] [%s] %s", timestamp, serviceId, message);
    }
    private String createLogMessage(String message) {
        String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
        return String.format("[%s] [%s] %s", timestamp, serviceInstance.getServiceId(), message);
    }
    private void writeLogToFile(String logMessage) {
        String SERVICE_ID = serviceInstance.getServiceId();
        String LOG_FILE_PREFIX = SERVICE_ID + "_log_";
        String LOG_FILE_EXTENSION = ".log";
        String fileName = LOG_FILE_PREFIX + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + LOG_FILE_EXTENSION;
        try (FileWriter fileWriter = new FileWriter(fileName, true)) { // 以追加模式打开文件
            fileWriter.write(logMessage + System.lineSeparator());
        } catch (IOException e) {

        }
    }
    private void writeFaiedLogToFile(String logMessage) {
        String SERVICE_ID = serviceId;
        String LOG_FILE_PREFIX = SERVICE_ID + "_log_";
        String LOG_FILE_EXTENSION = ".log";
        String fileName = LOG_FILE_PREFIX + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + LOG_FILE_EXTENSION;
        try (FileWriter fileWriter = new FileWriter(fileName, true)) { // 以追加模式打开文件
            fileWriter.write(logMessage + System.lineSeparator());

        } catch (IOException e) {
        }
    }
    public static void register() throws Exception{
        String serviceName="client";
        int port= 9001;
        String ipAddress="127.0.0.1";
        ServiceInstance serviceInstance=new ServiceInstance(serviceName,serviceId,ipAddress,port);
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(serviceInstance);

        String url="http://localhost:8880/api/register";

        HttpPost httpPost = new HttpPost(url);
        StringEntity entity = new StringEntity(json);
        httpPost.setEntity(entity);
        httpPost.setHeader("Content-Type", "application/json");
        // 设置超时
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(1000) // 连接超时设置为0.2秒
                .setSocketTimeout(1000)  // 读取超时设置为0.2秒
                .build();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            // 处理响应,不需要处理
        } catch (Exception e) {
        } finally {
            httpClient.close(); // 确保客户端被关闭
        }
    }
    public static void unregister() throws Exception{
        String serviceName="client";
        int port= 9001;
        String ipAddress="127.0.0.1";
        ServiceInstance serviceInstance=new ServiceInstance(serviceName,serviceId,ipAddress,port);
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(serviceInstance);
        String url="http://localhost:8880/api/unregister";
        HttpPost httpPost = new HttpPost(url);
        StringEntity entity = new StringEntity(json);
        httpPost.setEntity(entity);
        httpPost.setHeader("Content-Type", "application/json");
        // 设置超时
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(1000) // 连接超时设置为0.2秒
                .setSocketTimeout(1000)  // 读取超时设置为0.2秒
                .build();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            // 处理响应,不需要处理
        } catch (Exception e) {

        } finally {
            httpClient.close(); // 确保客户端被关闭
        }
    }
}
